package com.alnex.drools.service.impl;

import com.alnex.drools.config.drools.AddressRuleConfiguration;
import com.alnex.drools.service.ReloadDroolsRules;
import com.alnex.drools.utils.KieUtils;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.Message;
import org.kie.api.builder.Results;
import org.kie.internal.io.ResourceFactory;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.stereotype.Service;
import org.springframework.core.io.Resource;
import org.springframework.util.StringUtils;

import java.io.IOException;

@Service
public class ReloadDroolsRulesImpl implements ReloadDroolsRules {

    @Override
    public void reload(String drlName) throws Exception {
        KieServices kieServices = KieUtils.getKieServices();
        KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
        // 从数据库加载规则
        loadDBRules(drlName, kieFileSystem);

        // 从资源文件加载
        loadFileRules(drlName, kieFileSystem);

        KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem).buildAll();
        Results results = kieBuilder.getResults();
        if (results.hasMessages(Message.Level.ERROR)){
            System.out.println(results.getMessages());
            throw new IllegalStateException("### errors ###");
        }
    }

    private void loadDBRules(String drlName, KieFileSystem kieFileSystem) {
        // String path = "src/main/resources/rules/address.drl";
        String path = "src/main/resources/"+ AddressRuleConfiguration.RULES_PATH + drlName + ".drl";
        // 从数据库加载规则 TODO 未完成
        kieFileSystem.write(path,"package rules.address;\n" +
                "import com.alnex.drools.pojo.Address\n" +
                "import com.alnex.drools.model.fact.AddressCheckResult\n" +
                "rule \"[address] Postcode should be filled with exactly 5 numbers\"\n" +
                "    agenda-group \"address\" // rule 分组\n" +
                "    no-loop true\n" +
                "    lock-on-active true\n" +
                "    salience 1\n" +
                "    when\n" +
                "        $address : Address(postcode != null ,postcode matches \"([0-9]{5})\")\n" +
                "        $checkResult : AddressCheckResult()\n" +
                "    then\n" +
                "        $checkResult.setPostCodeResult(true);\n" +
                "        System.out.println(\"[address]规则中打印日志：校验通过!\");\n" +
                "end");
    }

    // 从classess/rules加载的规则
    private void loadFileRules(String drlName, KieFileSystem kieFileSystem) throws IOException {
        for (Resource file : getRuleFiles(drlName)) {
            kieFileSystem.write(ResourceFactory.newClassPathResource(AddressRuleConfiguration.BASE_RULES_PATH + AddressRuleConfiguration.RULES_PATH + file.getFilename(), "UTF-8"));
        }
    }

    private Resource[] getRuleFiles(String drlName) throws IOException {
        if(StringUtils.isEmpty(drlName)){
            ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
            return resourcePatternResolver.getResources(AddressRuleConfiguration.BASE_RULES_PATH + AddressRuleConfiguration.RULES_PATH + "**/*.*");
        }
        ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        return resourcePatternResolver.getResources(AddressRuleConfiguration.BASE_RULES_PATH + AddressRuleConfiguration.RULES_PATH + "**/"+ drlName + ".*");
    }
}
